/*              
Notifier.js
Represents object witch shows different messages to user

Author:         Volodymyr Lavrynovych (volodyalavrynovych@gmail.com)
Source url:     http://opensource.srirangan.net/notifier.js/
Date:           21.01.2012
Depends on:     JQuery 1.6
*/
(function ($) {

    //all settings of notifier in one object
    var config = window.NotifierjsConfig = {
        defaultTimeOut: 5000,
        removeTimeOut: 3000,
        debugMode: false,
        count: 0,
        position: ["top", "right"],
        notificationStyles: {
            padding: "12px 18px",
            margin: "0 0 6px 0",
            backgroundColor: "#000",
            opacity: 0.8,
            color: "#fff",
            font: "normal 13px 'Droid Sans', sans-serif",
            borderRadius: "5px",
            boxShadow: "#999 0 0 12px",
            width: "300px"
        },
        notificationStylesHover: {
            opacity: 1,
            boxShadow: "#000 0 0 12px"
        },
        container: $("<div style='margin-top: 40px'></div>")
    };

    //on page load adds container to page
    $(document).ready(function () {
        $("body").append(config.container);
    });

    //gets body of notification
    function getNotificationElement() {
        return $("<div>").css(config.notificationStyles).hover(function () {
            $(this).css(config.notificationStylesHover);
        }, function () {
            $(this).css(config.notificationStyles);
        });
    }

    //init notifier
    var notifier = window.Notifier = {};
    notifier.config = config; //sets config object

    //----------------------------------------------------------------------------------
    //configuring notifier
    notifier.config.container.css("position", "fixed");
    notifier.config.container.css("z-index", 9999);
    notifier.config.container.css(config.position[0], "12px");
    notifier.config.container.css(config.position[1], "12px");

    //----------------------------------------------------------------------------------
    //icons in base64 format
    notifier.errorIcon = "%3D%3D";
    notifier.warningIcon = "%3D";
    notifier.infoIcon = "%3D%3D";
    notifier.successIcon = "%3D";

    //----------------------------------------------------------------------------------
    //private methods

    /*---------------------------
    shows element
    
    element - DOM element to show
    timeOut - time out
    */
    notifier.showElement = function (element, timeOut) {
        notifier.config.count++;
        var notificationElement = getNotificationElement();

        notificationElement.append(element);

        if (timeOut) {
            notificationElement.delay(timeOut).fadeOut(function () {
                notificationElement.remove();
            });
        }

        //on click
        notificationElement.bind("click", function () {
            notificationElement.remove();
        });

        //om mouse out
        notificationElement.bind("mouseout", function () {
            notificationElement.delay(notifier.config.removeTimeOut).fadeOut(function () {
                notificationElement.remove();
            });
        });

        //shows notification
        notifier.config.container.prepend(notificationElement);
    };

    /*---------------------------
    shows customized notification

    message     - main message
    title       - title
    iconUrl     - url of icon
    timeOut     - time out
    hintMessage - message with small font size
    element     - additional element to show
    */
    notifier.customNotify = function (message, title, iconUrl, timeOut, hintMessage, element) {
        notifier.config.count++;
        var notificationElement = getNotificationElement();

        var tableElement = $("<table/>").css({
            border: '0px',
            width: '100%'
        });
        var rowElement = $("<tr/>");
        var contentCell = $("<td/>");

        if (timeOut) {
            timeOut = timeOut || notifier.config.defaultTimeOut;
        }

        var textElement = $("<div/>").css({
            display: 'inline-block',
            verticalAlign: 'middle',
            padding: (iconUrl ? '0px' : '0 12px'),
            width: '100%'
        });

        if (iconUrl) {
            var iconElement = $("<img/>", {
                src: iconUrl,
                css: {
                    width: 36,
                    height: 36,
                    display: "inline-block",
                    verticalAlign: "middle"
                }
            });

            var iconCell = $("<td/>");
            iconCell.css("width", "36px");
            iconCell.css("vertical-align", "top");

            iconCell.append(iconElement);
            rowElement.append(iconCell);
        }

        if (title) {
            var titleElement = $("<div/>");
            titleElement.append(document.createTextNode(title));
            titleElement.css("font-weight", "bold");

            textElement.append(titleElement);

        }

        if (message) {
            var messageElement = $("<div/>");
            messageElement.append(document.createTextNode(message));

            textElement.append(messageElement);
        }

        if (hintMessage) {
            var hr = $("<hr/>");
            hr.css("border", "#ffffff 0px");
            hr.css("border-bottom", "#999999 1px dashed");
            hr.css("margin-bottom", "2px");
            hr.css("margin-top", "2px");
            hr.css("width", "100%");

            var hint = $("<div/>");
            hint.css("font-size", "11px");
            hint.css("color", "#333333");
            hint.css("font-family", "tahoma, verdana, arial, sans-serif, Lucida Sans");
            hint.css("white-space", "pre-line");
            hint.css("overflow", "hidden");
            hint.css('white-space', 'pre-wrap');

            hint.append(document.createTextNode(hintMessage));
            textElement.append(hr);
            textElement.append(hint);
        }

        if (element) {
            textElement.append(element);
        }

        if (timeOut) {
            notificationElement.delay(timeOut).fadeOut(function () {
                notificationElement.remove();
            });
        }

        //on click
        notificationElement.bind("click", function () {
            notificationElement.remove();
        });

        //on mouse out
        notificationElement.bind("mouseout", function () {
            notificationElement.delay(notifier.config.removeTimeOut).fadeOut(function () {
                notificationElement.remove();
            });
        });

        contentCell.append(textElement);
        rowElement.append(contentCell);
        tableElement.append(rowElement);
        notificationElement.append(tableElement);

        //shows notification
        notifier.config.container.prepend(notificationElement);
    };


    /*---------------------------
    shows standart notification

    message     - main message
    title       - title
    iconUrl     - url of icon
    timeOut     - time out
    */
    notifier.notify = function (message, title, iconUrl, timeOut) {
        notifier.config.count++;
        var notificationElement = getNotificationElement();

        timeOut = timeOut || notifier.config.defaultTimeOut;

        if (iconUrl) {
            var iconElement = $("<img/>", {
                src: iconUrl,
                css: {
                    width: 36,
                    height: 36,
                    display: "inline-block",
                    verticalAlign: "middle"
                }
            });
            notificationElement.append(iconElement);
        }

        var textElement = $("<div/>").css({
            display: 'inline-block',
            verticalAlign: 'middle',
            padding: '0 12px'
        });

        if (title) {
            var titleElement = $("<div/>");
            titleElement.append(document.createTextNode(title));
            titleElement.css("font-weight", "bold");
            textElement.append(titleElement);
        }

        if (message) {
            var messageElement = $("<div/>");
            messageElement.append(document.createTextNode(message));
            textElement.append(messageElement);
        }

        //
        notificationElement.delay(timeOut).fadeOut(function () {
            notificationElement.remove();
        });

        //on click
        notificationElement.bind("click", function () {
            notificationElement.remove();
        });

        //shows notification
        notificationElement.append(textElement);
        notifier.config.container.prepend(notificationElement);
    };

    //----------------------------------------------------------------------------------
    //public methods

    //shows count of notification messages
    notifier.showMessagesCount = function () {
        var title = notifier.config.count + ' messages were showed';
        var message = 'And this is the ' + (notifier.config.count + 1) + 'th';
        notifier.customNotify(message, title, this.infoIcon, notifier.config.defaultTimeOut);
    };

    //shows info message with icon and title
    notifier.info = function (message, title) {
        notifier.customNotify(message, title, this.infoIcon, notifier.config.defaultTimeOut);
    };

    //shows warning message with icon and title
    notifier.warning = function (message, title) {
        notifier.customNotify(message, title, this.warningIcon, notifier.config.defaultTimeOut);
    };

    //shows error message with icon and title
    notifier.error = function (message, title) {
        notifier.customNotify(message, title, this.errorIcon, notifier.config.defaultTimeOut);
    };

    //shows success message with icon and title
    notifier.success = function (message, title) {
        notifier.customNotify(message, title, this.successIcon, notifier.config.defaultTimeOut);
    };

    //shows custom debug message if debug mode is on
    notifier.debug = function (message, title, code, timeOut) {
        if (!message) return;

        if (notifier.config.debugMode) {

            var debugTitle = 'Debug';
            var icon = notifier.infoIcon;
            timeOut = (timeOut ? timeOut : false);

            if (!title && !code) {
                notifier.customNotify(message, debugTitle, icon, timeOut);
            } else {
                debugTitle = (title ? debugTitle + ': ' + title : debugTitle);

                if (title && !code) {
                    notifier.customNotify(message, debugTitle, icon, timeOut, code);
                } else {
                    notifier.customNotify(message, debugTitle, icon, timeOut, code);
                }
            }
        }
    };

    notifier.debug("Debug is ON", null, null, 2000);

    //shows custom error
    notifier.customError = function (message, title, stackTrace, timeOut) {
        if (!message) return;

        var errorTitle = 'Error';
        var icon = notifier.errorIcon;
        timeOut = (timeOut ? timeOut : false);

        if (!title && !stackTrace) {
            notifier.customNotify(message, debug, icon, timeOut);
        } else {
            errorTitle = (title ? errorTitle + ': ' + title : errorTitle);

            if (title && !stackTrace) {
                notifier.customNotify(message, errorTitle, icon, timeOut, stackTrace);
            } else {
                notifier.customNotify(message, errorTitle, icon, timeOut, stackTrace);
            }
        }
    };

} (jQuery));